"use strict";

/**
 * author:Administrator
 * date:2015/12/2
 * desc: 工具类
 */
var errCodes = require('./err_code.js');
var config = require('../config/index.js');
var tokenRules = config.tokenRules;

var __utils = {};
module.exports = __utils;

/**
 * 日志
 */
var __logFlag = true;
function __appLog() {
  // should i use debug?
  if (__logFlag)
    return console.log.bind(console);
  else
    return function empty() {};
}
__utils.appLog = __appLog();

/**
 * 格式输出
 * errCode + result 是内部使用格式
 * status + result 是适配输出
 * @param data
 */
__utils.fout = function (data) {
  return {
    status: 200,
    errCode: 0,
    result: data || 'ok'
  };
};

/**
 * 格式化错误
 * errCode + result 是内部使用格式
 * status + result + message 是适配输出
 * @param errObj
 * @param extraMsg
 */
__utils.ferror = function (errObj, extraMsg) {
  return {
    status: errObj.code,
    message: {
      msg: extraMsg ? (errObj.msg + ' - ' + extraMsg) : errObj.msg
    },
    errCode: errObj.code,
    errMsg: extraMsg ? (errObj.msg + ' - ' + extraMsg) : errObj.msg
  }
};

var crypto = require('crypto');
/**
 * md5摘要
 * @param str
 */
__utils.md5 = function (str) {
  return crypto.createHash('md5').update(str).digest('hex');
};


/**
 * 生成token
 * @param uid
 * @param manager 
 * @param time 
 * @returns {string}
 */
__utils.genToken = function(uid, manager, time) {
  manager = typeof manager === 'undefined' ? '1' : manager;
  time = typeof time === 'undefined' ? new Date().getTime() : time;

  var md5Src = tokenRules.md5SrcPtn
    .replace('%uid', uid)
    .replace('%manager', manager)
    .replace('%time', time);
  var md5Result = __utils.md5(md5Src);
  var tokenSrc = tokenRules.tokenSrcPtn
    .replace('%uid', uid)
    .replace('%manager', manager)
    .replace('%time', time)
    .replace('%md5', md5Result);
  return encodeURIComponent(tokenSrc);
};

/**
 * 检验token的合法性
 * @param token
 */
__utils.checkToken = function (token) {
  if (!token) {
    __utils.appLog('token empty');
    return __utils.ferror(errCodes.E_ARGS_INVALID, 'token');
  }
  try {
    token = decodeURIComponent(token);
  } catch (e) {
    __utils.appLog('token decodeURIComponent exp:', e);
    return __utils.ferror(errCodes.E_ARGS_INVALID, 'token');
  }
  var index = token.indexOf(tokenRules.seperator);
  if (index < 0) {
    __utils.appLog('token no seperator :', tokenRules.seperator);
    return __utils.ferror(errCodes.E_ARGS_INVALID, 'token');
  }
  var pre = token.substr(0, index);
  var md5ToCheck = token.substr(index + tokenRules.seperator.length);
  var src = tokenRules.md5SrcPtn2.replace('%src', pre);
  var checkedMd5 = __utils.md5(src);
  if (checkedMd5 != md5ToCheck) {
    __utils.appLog('token md5 not equal');
    return __utils.ferror(errCodes.E_ARGS_INVALID, 'token');
  }

  // 取得变量
  var args = {};
  var rawArgs = pre.split('&');
  for (var kvPair of rawArgs) {
    var pair = kvPair.split('=');
    args[pair[0]] = pair[1];
  }
  // 检测时间
  var srcTime = args.time;
  var nowTime = new Date().getTime();
  if (nowTime - srcTime > tokenRules.tokenTimeOut) {
    __utils.appLog('token timeout');
    return __utils.ferror(errCodes.E_TOKEN_TIMEOUT);
  }
  return __utils.fout({uid: args.uid, manager: args.manager});
};


var dateFormat = require('dateformat');
var mkdirp = require('mkdirp');
var path = require('path');

var userFaceRootDir = config.dir.userRoot;
var datePtn = config.dir.datePtn;
var timePtn = config.dir.timePtn;
var userFname = config.dir.userFname;
var __counter = 1;

/**
 * 获取保存用户图片的 完整路径/相对路径
 * @param uid
 * @return {object} json
 */
__utils.getPath_userFace = function (uid) {
  var now = new Date();
  var nowDate = dateFormat(now, datePtn);

  var nowTime = dateFormat(now, timePtn);
  __counter++;
  var fileName = userFname.replace('%' + timePtn, nowTime).replace('%uid', uid).replace('%counter', __counter);
  var fullPath = path.join(userFaceRootDir, nowDate, fileName);
  var rpath = path.join(nowDate, fileName);
  return {
    fullPath: fullPath, // 完整文件路径
    rpath: rpath, // 相对文件路径
    fileName: fileName // 文件名
  };
};

//var starRoot = config.dir.starRoot;
var starFname = config.dir.starFname;
var starRpath = config.dir.starRpath;
var starFpath = config.dir.starFpath;
/**
 * 获取明星图片的 完整/相对路径
 * @param srcPath
 * @param starid
 */
__utils.getPath_starFace = function (srcPath, starid) {
  var rpath = starRpath.replace('%starid', starid); // 相对路径
  var fileName = starFname.replace('%starid', starid);
  var fullPath = starFpath.replace('%starid', starid);

  return {
    fullPath: fullPath, // 完整文件路径
    rpath: rpath, // 相对文件路径
    fileName: fileName // 文件名
  };
};

/**
 * 获取组件的保存位置
 * @param starid
 * @param otype
 */
__utils.getPath_parts = function (starid, otype) {
  var fileName = config.dir.partFname.replace('%starid', starid).replace('%otype', otype);
  var fullPath = config.dir.partFpath.replace('%starid', starid).replace('%otype', otype);
  var rurl = config.dir.partRurl.replace('%starid', starid).replace('%otype', otype);
  return {
    fullPath: fullPath, // 完整文件路径
    fileName: fileName,  // 文件名
    rurl: rurl, // 相对url
    fullUrl: config.rootUrl + rurl // 完整url
  };
};

/**
 * 获取渲染后图片的保存 相对位置
 * @param ufaceRpath 用户图片相对位置
 * 比如
 * a/b.jpg => a/b_out.jpg,
 * .jpg => _out.jpg
 * abc => abc_out
 */
__utils.getPath_rendered = function (ufaceRpath) {
  var outpath;
  var dotPos = ufaceRpath.lastIndexOf('.');
  if (dotPos < 0) dotPos = ufaceRpath.length;
  outpath = ufaceRpath.substr(0, dotPos) + '_out' + ufaceRpath.substr(dotPos, ufaceRpath.length);
  return outpath;
};

var fs = require('fs');
__utils.moveFile = function (src, dest) {
  // mkdir -p
  var seprator = dest.indexOf('/') === 0 ? '/' : '\\'; // default unix
  var lastSlashIndex = dest.lastIndexOf(seprator); // /a/b/c/.../aa.jpg
  var folder = dest.substr(0, lastSlashIndex);
  mkdirp.sync(folder, 0x666); // 生产路径

  // TODO bug:不在同一个分区,不能rename
  fs.renameSync(src, dest);
};

var request = require('request');
__utils.makeRequest_postForm = function (url, form) {
  return new Promise(function (fulfil, reject) {
    request.post({
      url: url,
      form: form
    }, function (err, httpResponse, body) {
      fulfil({err: err, body: body});
    });
  });
};